import pickle
import os
from datetime import datetime, date
from typing import List


class Task:
    def __init__(self, name, task_type='habit', value=5, unit=1, target=1, progress=0):
        self.name = name
        self.task_type = task_type
        self.value = value
        self.unit = unit
        self.target = target
        self.progress = progress

    def calculate_coins(self, quantity=1):
        if self.task_type == 'habit':
            return self.value if quantity > 0 else -self.valueq
        elif self.task_type == 'one_time':
            return self.value if quantity > 0 else 0
        elif self.task_type == 'progress':
            completed_units = quantity // self.unit
            return completed_units * self.value

    def is_completed(self):
        if self.task_type == 'progress':
            return self.progress >= self.target
        return False

    def show_progress(self):
        if self.task_type == 'progress':
            percent = self.progress / self.target * 100
            bar = '▓' * int(percent // 5) + '░' * (20 - int(percent // 5))
            print(f"{self.name} [{bar}] {percent:.1f}%")
        elif self.task_type == 'one_time':
            status = "✓" if self.is_completed() else "✗"
            print(f"{self.name} {status}")


class Account:
    def __init__(self):
        self.balance = 0
        self.history = []
        self.active_tasks: List[Task] = []

    def update_balance(self, task, quantity):
        change = task.calculate_coins(quantity)
        self.balance += change

        record = {
            "date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "task": task.name,
            "quantity": quantity,
            "change": change,
            "type": task.task_type
        }
        self.history.append(record)

        if task.task_type == 'progress':
            task.progress += quantity
            if task.is_completed():
                print(f"🎉 恭喜完成 {task.name}！")
                self.active_tasks.remove(task)
        elif task.task_type == 'one_time' and quantity > 0:
            self.active_tasks.remove(task)

    def save_to_file(self, filename="account_data.pkl"):
        with open(filename, "wb") as file:
            pickle.dump(self, file)

    @classmethod
    def load_from_file(cls, filename="account_data.pkl"):
        try:
            with open(filename, "rb") as file:
                return pickle.load(file)
        except FileNotFoundError:
            return cls()

    def show_balance(self):
        current_date = datetime.now().strftime("%Y年%m月%d日")
        print(f"\n截止{current_date}，金币余额为：{self.balance}")

    def show_history(self):
        print("\n📜 交易记录：")
        for record in self.history[-5:]:  # 显示最近5条记录
            status = "✅" if record['change'] >= 0 else "❌"
            print(f"{record['date']} {status} {record['task']}: {abs(record['change'])}金币")

    def clear_balance(self):
        self.balance = 0

    def clear_history(self):
        self.history = []


def handle_input(prompt, validator, retry=True):
    while True:
        try:
            value = input(prompt)
            return validator(value)
        except ValueError as e:
            if not retry:
                raise
            print(f"输入错误：{e}，请重新输入")


def generate_habits():
    return [
        Task("每日背单词", task_type='habit', value=10),
        Task("健身打卡", task_type='habit', value=15),
        Task("早起打卡", task_type='habit', value=8)
    ]


def load_custom_tasks():
    try:
        with open("custom_tasks.pkl", "rb") as f:
            return pickle.load(f)
    except (FileNotFoundError, EOFError):
        return []


def save_custom_tasks(tasks: List[Task]):
    with open("custom_tasks.pkl", "wb") as f:
        pickle.dump([t for t in tasks if not t.is_completed()], f)


def should_refresh_tasks():
    try:
        with open("last_run.date", "r") as f:
            last_date = date.fromisoformat(f.read().strip())
            return last_date < date.today()
    except FileNotFoundError:
        return True


def save_refresh_date():
    with open("last_run.date", "w") as f:
        f.write(str(date.today()))


def plan_next_day():
    print("\n=== 明日计划设置 ===")
    print("可以添加两种任务类型：")
    print("1. 一次性任务 - 完成后自动消失")
    print("2. 进度任务 - 需要持续完成的目标\n")

    new_tasks = []
    while True:
        name = handle_input(
            "任务名称（直接回车结束添加）: ",
            lambda x: x.strip(),
            retry=False
        )
        if not name:
            break

        task_type = handle_input(
            "任务类型 (1/2): ",
            lambda x: 'one_time' if x == '1' else 'progress',
            retry=True
        )

        value = handle_input(
            "任务金币值: ",
            lambda x: int(x) if x.isdigit() else ValueError("请输入数字"),
            retry=True
        )

        if task_type == 'progress':
            unit = handle_input(
                "每个单位包含多少数量（例如背单词10个/单位）: ",
                lambda x: int(x),
                retry=True
            )
            target = handle_input(
                "总目标数量: ",
                lambda x: int(x),
                retry=True
            )
            new_tasks.append(Task(name, task_type, value, unit, target))
        else:
            new_tasks.append(Task(name, task_type, value))

        print(f"已添加任务：{name}")

    return new_tasks


def main():
    # 删除旧的 account_data.pkl 文件
    if os.path.exists("account_data.pkl"):
        os.remove("account_data.pkl")
    account = Account.load_from_file()

    # 每日初始化
    if should_refresh_tasks():
        print("\n=== 新的一天开始啦！ ===")
        account.active_tasks = generate_habits()
        save_refresh_date()

    # 加载自定义任务
    account.active_tasks += load_custom_tasks()

    # 处理所有任务
    print("\n=== 今日任务 ===")
    for task in account.active_tasks.copy():
        print(f"\n当前任务：{task.name}")
        task.show_progress()

        if task.task_type == 'habit':
            res = handle_input(
                "是否完成？(y/n): ",
                lambda x: 'y' if x.lower() in ('y', 'n') else '',
                retry=True
            )
            qty = 1 if res == 'y' else 0
        else:
            qty = handle_input(
                "请输入完成数量: ",
                lambda x: int(x),
                retry=True
            )

        account.update_balance(task, qty)

    # 计划明日任务
    if input("\n是否要设置明日任务？(y/n): ").lower() == 'y':
        new_tasks = plan_next_day()
        account.active_tasks.extend(new_tasks)

    # 保存数据
    save_custom_tasks([
        t for t in account.active_tasks
        if t.task_type != 'habit' and not t.is_completed()
    ])
    account.save_to_file()

    # 显示最终状态
    account.show_balance()
    account.show_history()


if __name__ == "__main__":
    main()
print('a')